#pragma once
#include "request_session.h"
#include "base/callback/callback.h"
#include <mutex>

namespace threadpool {
	class ThreadPool;
}

namespace request {
	class RequestManager : public nbase::SupportWeakCallback
	{
	public:
		static RequestManager* GetInstance()
		{
			static RequestManager manager;
			return &manager;
		}
		RequestManager();
		~RequestManager();

		void Clear() {
			std::lock_guard<std::mutex> lock(mtx_map_request_);
			map_request_.clear();
		};

		void StopAllRequestSession();
		void PauseAllRequestSession();
		void ContinueAllRequestSession();

		const RequestSessionPtr GetRequestSession(const std::string& id, bool paused = false);

		//std::string InsertRequestSession(RequestSessionPtr session);
		RequestSessionPtr CreateRequestSession();
		bool StopRequestSession(const std::string& id);
		bool PauseRequestSession(const std::string& id);
		bool ContinueRequestSession(const std::string& id);
		bool RemoveRequestSession(const std::string& id);
		bool SwapRequestSessionToPaused(const std::string& id);
		bool SwapRequestSessionToRequest(const std::string& id);

	public:
		std::string AsynHttpRequest(const std::string& url, const std::string& data, int method, const SetRequestSessionParamCallback& setParamCallback, const RequestResultCallback& resultCallback);
		std::string SynHttpRequest(const std::string& url, const std::string& data, int method, const std::string& requestId, const SetRequestSessionParamCallback& setParamCallback = nullptr);

		std::string AsynFileRequest(const std::string& url, const std::string& data, const Form& form, int method, const SetRequestSessionParamCallback& setParamCallback, const RequestResultCallback& resultCallback);
		std::string SynFileRequest(const std::string& url, const std::string& data, const Form& form, int method, const std::string& requestId, const SetRequestSessionParamCallback& setParamCallback = nullptr);

		std::string AsynFileDownload(const std::string& url, const std::string& dir, const SetRequestSessionParamCallback& setParamCallback, const DownloadProgressCallback& progressCallback, const RequestResultCallback& resultCallback);
		std::string	SynFileDownload(const std::string& url, const std::string& dir, DownloadProgressCallbackPtr pProgressCallback, RequestResultCallbackPtr pResultCallback, const std::string& requestId, const SetRequestSessionParamCallback& setParamCallback = nullptr);

		std::string AsynResumeDownload(const std::string& requestId);
		std::string	SynResumeDownload(const std::string& requestId);

		std::string AsynHttpRequestStream(const std::string& url, const std::string& data, int method, const SetRequestSessionParamCallback& setParamCallback, parse_recv_callback parseBodyCallback, const RequestResultCallback& resultCallback);
	protected:
		void HttpRequestCallback(const std::string& requestId, const std::string& url, const std::string& data, int method, const RequestResultCallback& resultCallback);
		void FileRequestCallback(const std::string& requestId, const std::string& url, const std::string& data, const Form& form, int method, const RequestResultCallback& resultCallback);
		void FileDownloadCallback(const std::string& requestId, const std::string& url, const std::string& dir, DownloadProgressCallbackPtr pProgressCallback, RequestResultCallbackPtr pResultCallback);
		void ResumeDownloadCallback(const std::string& requestId);

	private:
		std::map<std::string, RequestSessionPtr>		map_request_;					//k: seesionId;  v-
		std::map<std::string, RequestSessionPtr>		map_request_paused_;			//k: seesionId;  v-
		std::mutex mtx_map_request_;

		int auto_request_index_{ 0 };
		threadpool::ThreadPool* thread_pool_{ nullptr };
	};
}






